#include "parkinglotmainwindow.h"
#include "ui_parkinglotmainwindow.h"
//调用摄像头
#include <QCameraInfo>
#include <QCamera>
#include <QCameraViewfinder>
#include <QCameraImageCapture>
#include <QPixmap>
//弹窗
#include <QMessageBox>
//获取时间
#include <QDateTime>
//识别
#include <QDebug>
#include <QBuffer>
#include <QTextCodec>
#include <QFileDialog>
#include <QByteArray>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include <QMessageBox>
#include <QScreen>
#include <QPainter>
#include "screenwidget.h"

ParkingLotMainWindow::ParkingLotMainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::ParkingLotMainWindow)
{
    ui->setupUi(this);

    CreateDatabaseFunc();//调用函数创建且打开数据库
    //CreateTableFunc();//调用函数创建数据表
    onShowUserDb("select * from parking_lot ");//在窗口上显示出数据库内容
    left_car();
    //获取可用摄像头设备并输出在控制台
    QList<QCameraInfo> infos = QCameraInfo::availableCameras();
    qDebug() << infos.value(0).deviceName() << ":" <<infos.value(0).description();
    QString camera = infos.value(0).deviceName();
    qDebug() << camera;
    //显示摄像头
    ca =new QCamera(camera.toUtf8() ,this );
    ui->camera->show();
    QCameraViewfinder *v2 = new QCameraViewfinder(ui->camera);
    v2->resize(ui->camera->size());
    ca->setViewfinder(v2);
    v2->show();
    ca->start();

    //识别
    d=new Dialog(this);//先实例化tokenDialog
    this->setWindowTitle("mOCR");
    ui->actionaction_C->setChecked(true);
    //on_actionaction_C_toggled(true);//自动复制到截切版
}

ParkingLotMainWindow::~ParkingLotMainWindow()
{
    delete ui;
}

void ParkingLotMainWindow:: CreateDatabaseFunc()
{
    //1：添加数据库驱动
    sqldb = QSqlDatabase::addDatabase("QSQLITE") ;

    //2：设置数据库名称
    sqldb.setDatabaseName("studentmanagement.db");

    //3:打开此数据库是否成功
    if(sqldb.open()==true)
    {
        QMessageBox::information(0,"正确","恭喜你，数据库打开成功！",QMessageBox::Ok);
    }
    else
    {
        QMessageBox::critical(0,"错误","数据库打开失败，请重新检测！",QMessageBox::Ok);
    }
}//创建SQLite数据库 打开连接

void ParkingLotMainWindow:: CreateTableFunc()
{
    QSqlQuery createquery;//执行查询sql语句的类对象

    //创建SQL语句
    QString strsql=QString("create table parking_lot(car_number text primary key not null , in_time text , out_time text , money int, state text  )");

    //执行SQL语句
    if(createquery.exec(strsql)==false)
    {
        QMessageBox::critical(0,"失败","数据表创建失败，请重新检查！",QMessageBox::Ok);
    }
    else
    {
        QMessageBox::information(0,"成功","恭喜你，数据表创建成功！",QMessageBox::Ok);
    }
}//创建SQLite数据表

void ParkingLotMainWindow:: QueryTableFunc()
{//执行查询操作

}

void ParkingLotMainWindow::on_pushButton_capture_clicked()
{//拍下车牌号码
    //截取用户打卡时的图片
    capture = new QCameraImageCapture(ca);
   // capture->capture("D://c_shixun//picture//1.jpg");
    capture->capture("1.jpg");
    //"C:\Users\13365\Pictures\1.jpg"
    QMessageBox::information(this, "成功", "恭喜你，拍照成功！");
    //ui->label_7->setPixmap(QPixmap('"C:\\Users\\86157\\Pictures\\1.jpg"'));
    QImage* image = new QImage;
        image->load("C:\\Users\\86157\\Pictures\\1.jpg");
        ui->label_7->setPixmap(QPixmap::fromImage(*image));
}

void ParkingLotMainWindow::on_pushButton_count_clicked()
{//计算停车费用
    QSqlQuery sqlquery;
    QString car_number =ui->textEdit->toPlainText();//获取识别出来的车牌号码
    QString sql = QString("select * from parking_lot where car_number = '%1' and state = '已完成' and money is NULL ").arg(car_number);//找出对应条件的车辆信息
    sqlquery.exec(sql);
    sqlquery.next();
    QString in_time = sqlquery.value(1).toString();//获取数据库中车子入库时间
    QString out_time = sqlquery.value(2).toString();//获取数据库中车子出库时间
    QDateTime time_in = QDateTime::fromString(in_time,"yyyy-MM-dd hh:mm");//将入库时间的字符串转换成时间戳
    QDateTime time_out = QDateTime::fromString(out_time,"yyyy-MM-dd hh:mm");//将入库时间的字符串转换成时间戳
    int seconds = time_in.secsTo(time_out);//将出入库时间差用秒表示
    int n = seconds/360;
    int money;
    if(seconds < (30*60))
    {//半个小时内免费
        sql = QString("update parking_lot set money = 0 where car_number = '%1' and state = '已完成' and money is NULL").arg(car_number);
        sqlquery.exec(sql);
        onShowUserDb("select * from parking_lot");//将费用展示也展示在窗口上
        return ;
    }
    if(seconds%360 == 0)
    {//每个小时两块钱
        money = 2 * n;
    }
    else
    {//不足一个小时算一个小时
        money = 2 * (n+1);
    }
    if(money>25)
    {//每天最高收25元
        money = 25;
    }
    sql = QString("update parking_lot set money = %1 where car_number = '%2' and state = '已完成' and money is NULL").arg(money).arg(car_number);
    sqlquery.exec(sql);
    onShowUserDb("select * from parking_lot");
}

void ParkingLotMainWindow::on_pushButton__search_clicked()
{//查询对应车牌号码的信息
    QSqlQuery sqlquery;
    QString sql = "select * from parking_lot where";
    QString car_number =ui->lineEdit->text();//获取要查询的车牌号码
    if(car_number ==""){
       QMessageBox::critical(this,"失败","提示：查询条件不能为空",QMessageBox::Ok);
       return;
    }
    sql += " car_number = '" + car_number +"'";
    sqlquery.exec(sql);
    //检测数据库中是否有对应的车子
    if(sqlquery.next()==false){
        QMessageBox::critical(nullptr,"失败","系统中没有该车牌号码",QMessageBox::Ok);
    }else{
        QMessageBox::information(nullptr,"成功","恭喜您，查询成功",QMessageBox::Ok);
    }
    onShowUserDb(sql);//将查询结果显示出来
}

void ParkingLotMainWindow::on_pushButton_delete_clicked()
{//删除对应车牌号码的信息
    QSqlQuery sqlquery;
    QString car_number =ui->lineEdit ->text();//获取要删除的车牌号码
    if(car_number==""){
        QMessageBox::critical(this,"失败","提示：请你输入要删除的车牌号",QMessageBox::Ok);
        return ;
    }
    QString sql = "select * from parking_lot where car_number = '"+car_number+"'";
    sqlquery.exec(sql);
    //检测数据库中是否有对应的车子
    if(sqlquery.next()==false){
        QMessageBox::critical(0,"失败","系统中没有该车牌号码",QMessageBox::Ok);
    }else{
        sql = QString("delete from parking_lot where car_number = '%1' ").arg(car_number);//删除数据库中该车子的信息
        sqlquery.exec(sql);
        QMessageBox::information(nullptr,"成功","恭喜您，删除成功",QMessageBox::Ok);
    }
    onShowUserDb("select * from parking_lot");
}

void ParkingLotMainWindow::onShowUserDb(QString select_sql)
{//数据初始化
    //QString select_sql = "select * from student;";//sql
    QTableWidget *tableWidget = ui->tableWidget;
    int c = 0, r = 0, nColumn, nRow;
    QSqlQuery sql_query;
    sql_query.prepare(select_sql);
    sql_query.exec();
    sql_query.last();//指向最后一个数据
    nRow = sql_query.at() + 1;//计算行数
    tableWidget->setRowCount(nRow);//设置表行
    nColumn = tableWidget->columnCount();
    sql_query.first();
    while(r<nRow)//行
    {
        for(c = 0; c<nColumn; c++)
        {//列
            tableWidget->setItem(r,c,new QTableWidgetItem(sql_query.value(c).toString()));
        }
        r++;
        sql_query.next();
    }
}

void ParkingLotMainWindow::on_pushButton_identifiy2_clicked()
{//出库
    QSqlQuery sqlquery;
    QString car_number =ui->textEdit->toPlainText();//获取识别出的车牌号码
    if(car_number=="")
    {
        QMessageBox::critical(0,"失败","未识别到车牌号码，请重新识别！",QMessageBox::Ok);
        return ;
    }
    QString timestr = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm");//获取出库时间
    QLineEdit *lineEdit = ui->lineEdit_3;
    lineEdit->setText(timestr);//显示出库时间
    QString time =ui->lineEdit_3->text();
    QString sql = QString("update parking_lot set out_time = '%1',state = '已完成' where car_number = '%2' and state = '未完成'").arg(time).arg(car_number);//将出库的信息写入数据库
    if(sqlquery.exec(sql))
    {
        QMessageBox::information(0,"成功","出库成功！",QMessageBox::Ok);
        onShowUserDb("select * from parking_lot");
        left_car();//出库成功后显示剩余车位
    }
    else
    {
        QMessageBox::critical(0,"失败","出库失败！",QMessageBox::Ok);
    }
}

void ParkingLotMainWindow::on_pushButton_identifiy1_clicked()
{//入库
    QSqlQuery sqlquery;
    void on_shibie();
    QString car_number =ui->textEdit->toPlainText();//获取识别出的车牌号码

    if(car_number=="")
    {
        QMessageBox::critical(0,"失败","您未输入车牌号，请重新输入！",QMessageBox::Ok);
        return ;
    }
    QString timestr = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm");//获取入库时间
    QLineEdit *lineEdit = ui->lineEdit_3;
    lineEdit->setText(timestr);//显示入库时间
    QString time =ui->lineEdit_3->text();
    QString strs=QString("insert into parking_lot values('%1','%2','',NULL,'未完成')").arg(car_number).arg(time);//将入库的信息写入数据库
    if(sqlquery.exec(strs)==false){
        QMessageBox::critical(nullptr,"失败","入库失败!",QMessageBox::Ok);
    }else{
        QMessageBox::information(nullptr,"成功","入库成功!",QMessageBox::Ok);
        onShowUserDb("select * from parking_lot ");
        left_car();
    }
}


void ParkingLotMainWindow::left_car()
{//计算剩余车位
    QLineEdit *lineEdit = ui->lineEdit_left;
    int nRow, left;
    QString sql = "select * from parking_lot where state = '未完成'";//找出在车库中的车辆信息
    QSqlQuery sqlquery;
    sqlquery.exec(sql);
    sqlquery.last();//指向最后一个数据
    nRow = sqlquery.at()+1 ;//计算已入库的车子数量
    if(nRow>0)
    {
        left = 100-nRow;
    }
    else
    {
        left = 100;
    }
    QString number = QString::number(left);//将整数left转换为字符串
    lineEdit->setText(number);//显示出剩余车位
}

void ParkingLotMainWindow::on_action_AI_triggered()
{

    d->exec();//模态对话框

}
//转图片格式
void ParkingLotMainWindow::convertPic(QByteArray &arr)
{
    pix=ui->label_7->pixmap();
    //image改成Base64格式
    QByteArray ba;
    QBuffer buf(&ba);
    buf.open(QIODevice::WriteOnly);
    pix->save(&buf,"JPG");
    QByteArray base64=ba.toBase64();//对图片做Base64编码，不包含编码头

    QTextCodec *code=QTextCodec::codecForName("UTF-8");
    //对图片urlencode
    QByteArray imageData="image="+code->fromUnicode(base64).toPercentEncoding();
    arr=imageData;
}
void ParkingLotMainWindow::copy2Clip()
{
    ui->textEdit->selectAll();
    ui->textEdit->copy();
}
//从文件打开
void ParkingLotMainWindow::on_actFromFile_triggered()
{
    QString str=QFileDialog::getOpenFileName(this,"选择图片","./","图片文件(*.png *.jpg)");
    ui->label_7->setPixmap(QPixmap(str));
}
void ParkingLotMainWindow::on_actionaction_C_toggled(bool arg1)
{
    if(arg1)
        connect(this,&ParkingLotMainWindow::recgFinished,[this]{this->copy2Clip();});
    else {
        disconnect(this,&ParkingLotMainWindow::recgFinished,this,&ParkingLotMainWindow::copy2Clip);
    }
}
//截图
void ParkingLotMainWindow::on_actFromClip_triggered()
{
    this->setWindowOpacity(0);//设置窗口透明度达到隐藏的效果
    QPixmap p=QGuiApplication::primaryScreen()->grabWindow(0);
    screenWidget *w=new screenWidget(this);
    connect(w,&screenWidget::cut,this,&ParkingLotMainWindow::on_cut);
    w->totalScreen=p;
    w->setWindowFlag(Qt::Window);
    w->showFullScreen();//子窗口showFullScreen无效，需要先setWindowFlag
    this->setWindowOpacity(100);
}
//截图完毕，显示到QLabel
void ParkingLotMainWindow::on_cut(QPixmap p)
{
    ui->label_7->setPixmap(p);
}
//精准识别
void ParkingLotMainWindow::on_shibie()
{
    QByteArray arr;
    convertPic(arr);
    QByteArray repData;
    QString url=QString("https://aip.baidubce.com/rest/2.0/ocr/v1/accurate_basic?access_token=%1").arg(d->access_token);
    MHttp h;
    if(h.post_sync(url,arr,repData)){
        ui->textEdit->clear();
        QJsonDocument doc=QJsonDocument::fromJson(repData);
        QJsonArray jArr=doc.object().value("words_result").toArray();
        for(int i=0;i<jArr.size();i++){
            ui->textEdit->append(jArr.at(i).toObject().value("words").toString());
        }
    }else{
        QMessageBox::warning(this,"警告","识别失败，请检查网络或重试！");
    }
    emit recgFinished();
}

void ParkingLotMainWindow::on_pushButton_clicked()
{
    QByteArray arr;
    convertPic(arr);
    QByteArray repData;
    QString url=QString("https://aip.baidubce.com/rest/2.0/ocr/v1/accurate_basic?access_token=%1").arg(d->access_token);
    MHttp h;
    if(h.post_sync(url,arr,repData)){
        ui->textEdit->clear();
        QJsonDocument doc=QJsonDocument::fromJson(repData);
        QJsonArray jArr=doc.object().value("words_result").toArray();
        for(int i=0;i<jArr.size();i++){
            ui->textEdit->append(jArr.at(i).toObject().value("words").toString());
        }
    }else{
        QMessageBox::warning(this,"警告","识别失败，请检查网络或重试！");
    }
    emit recgFinished();

}
